/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#ifndef __GUI_DXGUIRENDERER_H__
#define __GUI_DXGUIRENDERER_H__

#pragma once

#include "IGUIRenderer.h"
#include "geom/Vector.h"

#include <d3dx9.h>

namespace gui {

/// Initialize the coreGUI as a DirectX component with an existing DirectX device
GUI_EXPORT 
bool coreInitDXGUIRenderer( LPDIRECT3DDEVICE9 pd3dDevice );

/// Destroy the DirectX implementation of the coreGUI
GUI_EXPORT
bool coreDestroyDXGUIRenderer();


#define D3DFVF_SCREENVERTEX ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
/// The DirectX struct for a vertex on screen
struct ScreenVertex
{
	float x, y, z, rhw;
	DWORD color;
	float tu, tv;
};

/**
 * \ingroup coreGUI
 *
 * The DXGUIRenderer class.<br>
 * Uses DirectX functionality to renderer GUI elements
 *
 * \date 05-02-2007
 *
 * \author juckel
 * 
 * \todo Modify for custom vertex format?
 * \todo Speedup rendering
 *
 */
class DXGUIRenderer :
	public IGUIRenderer
{
public:
	void clear();
	/// Draw a non filled rectangle on screen
	void drawRect(int x, int y, int width, int height, const math::Vector4 &color);
	void drawRoundRect(int x, int y, int width, int height, const math::Vector4 &color);

	/// Draw a filled rectangle on screen
	void drawFilledRect(int x, int y, int width, int height, const math::Vector4 &color);
	
	/// Draw a textured rectangle on screen. A subset of a texture can be specified
	void drawTexturedRect(int x, int y, int width, int height, int texX, int texY);

	/// Draw a circle on screen
	void drawCircle(int x, int y, float radius, int segments, const math::Vector4 &color);
	
	/// Draw a filled circle on screen
	void drawFilledCircle(int x, int y, float radius, int segments, const math::Vector4 &color);

	/// Enable rendering state for the GUI
	void enableGUIState();

	/// Disable the GUIs rendering state
	void disableGUIState();

	/// Return the current screen size
	math::Vector2i getScreenSize();

	DXGUIRenderer(void);
	virtual ~DXGUIRenderer(void);
	
	LPDIRECT3DDEVICE9 pd3dDevice;		///< The Direct3D Rendering device
protected:
	void createVertexDecl();

	LPDIRECT3DVERTEXBUFFER9 pRectBuffer;
	LPDIRECT3DVERTEXBUFFER9 pRectBuffer2;
	LPDIRECT3DVERTEXBUFFER9 pFilledRectBuffer;
	LPDIRECT3DVERTEXBUFFER9 pCircleBuffer;
	LPDIRECT3DVERTEXBUFFER9 pFilledCircleBuffer;
	int lastSegments;

	void *pVertices;
	ScreenVertex *pCircleVertices;
	ScreenVertex *pFilledCircleVertices;

	LPDIRECT3DVERTEXDECLARATION9 pRectDecl;

	LPDIRECT3DSTATEBLOCK9 pStateBlock;
	LPDIRECT3DSTATEBLOCK9 pOldStateBlock;
};

} // namespace

#endif
